Skip to content

cleanup: remove mesh-offline diag logs, plug JWT leaks, throttle retry-loop spam#62

Merged
mikhailm-coder merged 3 commits into
masterfrom
cleanup/remove-mesh-offline-diag-logs
Jul 7, 2026
Merged

cleanup: remove mesh-offline diag logs, plug JWT leaks, throttle retry-loop spam#62
mikhailm-coder merged 3 commits into
masterfrom
cleanup/remove-mesh-offline-diag-logs

Conversation

@mikhailm-coder

@mikhailm-coder mikhailm-coder commented Jul 7, 2026

Copy link
Copy Markdown

Summary

Post-mortem cleanup after the mesh-offline investigation. Removes temporary diagnostic logging, plugs two cleartext JWT leaks, and cuts the control-channel log spam that dominates client log volume.

Two commits:

  1. Remove diag logs + throttle control-channel telemetry to 10m
  2. Throttle offline-retry-loop log spam (AutoRetry / disconnect / LOST)

Why (data)

Analyzed 80,638 tool_id=meshcentral-agent lines across 114 real client logs. Mesh logging was 38.7% of all client log volume, dominated by an offline-retry storm:

Count % of mesh Message Action
22,071 27.4% AutoRetry Connect in N ms throttled (commit 2)
12,641 15.7% Control channel disconnected throttled (commit 2)
12,110 15.0% Connection LOST: ...before full auth throttled (commit 2)
10,705 13.3% Openframe JWT: <token> removed - cleartext token leak (commit 1)
8,129 10.1% Connection FAILED: No HTTP response throttled 60s->10m (commit 1)
6,765 8.4% Connection FAILED: Network timeout throttled 60s->10m (commit 1)

The JWT leak was logging full bearer tokens across 24 machines in production.

Changes

Removed

  • OrphanProof MeshID logging (temporary investigation markers) in MeshServer_ConnectEx and importSettings.
  • Two cleartext JWT leaks: Openframe token: read JWT ... in token_extractor.c (reverts that file to pre-investigation state, supersedes fix: make Openframe token diag line parseable by openframe-client #59) and the older Openframe JWT line in agentcore.c.

Kept, but throttled - the control-channel dial/failure telemetry (redacts proxy creds, carries correlation IDs):

  • Raised steady-state throttle 60s -> 10m via a new CONTROL_CHANNEL_LOG_THROTTLE_MS.
  • Extended the existing controlChannelLogThisAttempt gate to the per-cycle retry-loop messages (AutoRetry / disconnect / pre-auth LOST), collapsing an offline agent's spam to one logged set per 10m.
  • Clarified sampled lines with a (latest attempt) marker and renamed the counter to suppressed_since_last.

Deliberately left always-on

  • The un-throttled Connection FAILED: HTTP <code> lines (they fire only when the server responds non-101 - not offline spam).
  • The post-auth Connection LOST: Disconnected after authentication line (rare, meaningful state change).

Impact

Estimated ~85-90% reduction in mesh log volume for offline agents, with zero loss of state-transition logs (connect success, handshake, post-auth disconnect). Target changes still log immediately; suppressed attempts are counted.

Testing

Not yet built in this environment (no toolchain configured here). Changes are removals + wording + guarding existing printfs with an already-computed flag - no format-specifier or arg-count changes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Reduced repeated connection and retry log noise for control-channel issues.
    • Improved disconnect and connection-failure messages to better reflect the latest attempt and network-timeout cases.
    • Removed several sensitive or overly verbose diagnostic messages during connection setup and token handling.

mikhailm-coder and others added 2 commits July 7, 2026 12:50
…ing to 10m

The mesh-offline investigation is resolved. Drop the temporary diagnostic
logging added during it, and dial back the telemetry worth keeping.

Removed:
- OrphanProof MeshID logging in MeshServer_ConnectEx and importSettings
  (temporary investigation markers).
- Two cleartext JWT leaks that printed the full bearer token to logs: the
  "Openframe token: read JWT" line in token_extractor.c (this reverts that
  file to its pre-investigation state, superseding #59) and the older
  "Openframe JWT" line in agentcore.c.

Kept the control-channel dial/failure telemetry (fe2ce65): it's throttled,
redacts proxy credentials, and carries correlation IDs for future triage.
Raised the steady-state throttle from 60s to 10m via a new
CONTROL_CHANNEL_LOG_THROTTLE_MS define; target changes still log immediately
and suppressed attempts are still counted.

Clarified the throttled-log wording so a sampled line reads as one: the dial
line is tagged "(latest attempt)" with the counter renamed to
suppressed_since_last, and the two throttled "Connection FAILED" lines are
tagged "(latest attempt)" too. The un-throttled HTTP-response failure lines
are left unmarked since they print on every attempt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… / LOST)

Analysis of 80,638 meshcentral-agent lines across 114 client logs showed the
control-channel retry loop dominates agent log volume on offline machines:

  AutoRetry Connect in N ms                       22,071  (27% of mesh lines)
  Control channel disconnected [fd, authState]    12,641  (16%)
  Connection LOST: ...before full authentication  12,110  (15%)

These fire once per ~5-minute reconnect cycle and were un-throttled, making
mesh logging ~39% of all client log volume.

Gate them on the existing controlChannelLogThisAttempt flag (computed per dial
in MeshServer_ConnectEx), so an offline agent's whole per-cycle spam collapses
to one logged set per 10 min - the same window as the dial/FAILED lines. Rare
or first events still log immediately (a long gap flips the flag back on).

The post-auth "Disconnected after authentication" line is left always-on: it's
low-volume and marks a real state change (a healthy session closing), not
offline spam.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@mikhailm-coder, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5db3940a-4d1e-4744-a417-2e76f6d2e308

📥 Commits

Reviewing files that changed from the base of the PR and between cca59b6 and a93ad18.

📒 Files selected for processing (1)
  • meshcore/agentcore.c
📝 Walkthrough

Walkthrough

Adds a centralized throttle constant for control-channel logging, gates dial/retry/disconnect log lines behind a throttle flag, rephrases connection-failure log messages with more structured detail, and removes several debug/diagnostic prints (OrphanProof MeshID, Openframe JWT, decrypted JWT UTC printf) from agentcore.c and token_extractor.c.

Changes

Control-channel and token logging reduction

Layer / File(s) Summary
Throttle constant and dial/retry log gating
meshcore/agentcore.c
Introduces CONTROL_CHANNEL_LOG_THROTTLE_MS (600000ms) and uses it to gate dial logging in MeshServer_ConnectEx and the "AutoRetry Connect" log.
Disconnect and failure logging updates
meshcore/agentcore.c
Reworks disconnect logging in MeshServer_OnResponse behind controlChannelLogThisAttempt, and updates "Connection FAILED" and network-timeout log messages with expanded structured detail.
Removal of debug/diagnostic prints
meshcore/agentcore.c, openframe/token_extractor.c
Removes OrphanProof MeshID diagnostics (connection setup and settings import), the Openframe JWT debug print, and the decrypted JWT UTC timestamp printf (plus its <time.h> include).

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs

Suggested reviewers: denys-gif

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: removing diagnostic logs, fixing JWT leaks, and throttling retry-loop spam.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cleanup/remove-mesh-offline-diag-logs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
meshcore/agentcore.c (1)

4749-4794: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Throttle the DNS-failure retry path too meshcore/agentcore.c:4626-4631,5009-5011 The unresolved-host branch still prints agentcore: Could not resolve on every retry, and MeshServer_Connect() reuses controlChannelLogThisAttempt from the previous attempt. Move the throttle update into the resolve-failure branch or guard that print there so the offline/no-cache path uses the same 10-minute gate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@meshcore/agentcore.c` around lines 4749 - 4794, The DNS failure retry path
still logs on every reconnect because the unresolved-host branch in
MeshServer_Connect() bypasses the same throttling used for control-channel
attempts. Update the resolve-failure handling near the agentcore “Could not
resolve” print to use the same
controlChannelLogThisAttempt/controlChannelLastLogTick gating as the dialing
path, so repeated offline/no-cache retries only emit once per throttle window.
Keep the fix aligned with the existing attempt logging state on
agent->controlChannelLogThisAttempt, agent->controlChannelLastLogTick, and
agent->controlChannelDialSig.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@meshcore/agentcore.c`:
- Around line 4749-4794: The DNS failure retry path still logs on every
reconnect because the unresolved-host branch in MeshServer_Connect() bypasses
the same throttling used for control-channel attempts. Update the
resolve-failure handling near the agentcore “Could not resolve” print to use the
same controlChannelLogThisAttempt/controlChannelLastLogTick gating as the
dialing path, so repeated offline/no-cache retries only emit once per throttle
window. Keep the fix aligned with the existing attempt logging state on
agent->controlChannelLogThisAttempt, agent->controlChannelLastLogTick, and
agent->controlChannelDialSig.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8e33c254-5b86-4adf-a9de-41b0e03d2058

📥 Commits

Reviewing files that changed from the base of the PR and between 571f6af and cca59b6.

📒 Files selected for processing (2)
  • meshcore/agentcore.c
  • openframe/token_extractor.c
💤 Files with no reviewable changes (1)
  • openframe/token_extractor.c

Addresses CodeRabbit review on #62: the "Could not resolve" retry path in
MeshServer_ConnectEx bypassed the throttle. When resolution fails
(sin6_family == AF_UNSPEC, no proxy, no cached IP), the block that computes
controlChannelLogThisAttempt is skipped, so the "agentcore: Could not resolve"
print fired on every retry and the stale flag leaked into the downstream
AutoRetry log decision.

Throttle it here on the same CONTROL_CHANNEL_LOG_THROTTLE_MS (10m) gate, using
an "UNRESOLVED" dial signature so a resolved<->unresolved flap still logs
immediately, and set controlChannelLogThisAttempt so the AutoRetry log stays
consistent. Adds the suppressed_since_last counter for parity with the dial
line.

Not observed in the current client-log sample (0 occurrences) - offline agents
there all resolved DNS and failed at the TCP/HTTP layer - but this closes the
one remaining un-throttled retry path for agents offline due to DNS failure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mikhailm-coder

Copy link
Copy Markdown
Author

Addressed in a93ad18: throttled the Could not resolve retry path on the same CONTROL_CHANNEL_LOG_THROTTLE_MS (10m) gate with an UNRESOLVED signature, and set controlChannelLogThisAttempt so the downstream AutoRetry log stays consistent. @coderabbitai please re-review.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 62 --repo flamingo-stack/meshagent --json commits --jq '.commits[] | "\(.oid) \(.messageHeadline)"' | tail -20
echo "---diff---"
gh api repos/flamingo-stack/meshagent/commits/a93ad18 --jq '.files[].filename'
echo "---patch---"
gh api repos/flamingo-stack/meshagent/commits/a93ad18 --jq '.files[].patch'

Length of output: 2277


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cd $(fd -t d meshagent -d 1 || echo .) 2>/dev/null || true
fd agentcore.c
FILE=$(fd agentcore.c | head -1)
echo "FILE=$FILE"
grep -n "controlChannelDialSig\|controlChannelLastLogTick\|controlChannelSuppressed\|controlChannelLogThisAttempt\|CONTROL_CHANNEL_LOG_THROTTLE_MS\|ILibGetUptime" -R "$FILE" -n | head -80
echo "---struct definition---"
rg -n "controlChannelDialSig|controlChannelLastLogTick|controlChannelSuppressed|controlChannelLogThisAttempt" --type=c -g '*.h' 
</shell>

Length of output: 3154


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "controlChannelDialSig|controlChannelLastLogTick|controlChannelSuppressed|controlChannelLogThisAttempt|controlChannelDialTick" git -g '*.h'

Length of output: 527


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "controlChannelDialSig|controlChannelLastLogTick|controlChannelSuppressed|controlChannelLogThisAttempt|controlChannelDialTick" --type=h -g '*.h' . || true
fd -e h | xargs grep -ln "controlChannelDialSig" 2>/dev/null

Length of output: 899


@mikhailm-coder Thanks, I reviewed a93ad18. The DNS-resolution-failure throttle looks correct and consistent with the existing dial-path pattern:

  • The new "UNRESOLVED" signature check at Line 4634-4643 in meshcore/agentcore.c mirrors the logic already used for the dial/failure pair (Line 4794), using the same CONTROL_CHANNEL_LOG_THROTTLE_MS (10-minute) gate.
  • Field usage matches the declared types in meshcore/agentcore.h (controlChannelDialSig[160], controlChannelLastLogTick as long long, controlChannelSuppressed as unsigned int, controlChannelLogThisAttempt as int), so strcpy_s/%u formatting is all consistent.
  • Using a distinct "UNRESOLVED" signature nicely preserves immediate logging on a resolved↔unresolved flap, which is a good edge case to handle.
  • Setting controlChannelLogThisAttempt here correctly keeps the downstream AutoRetry Connect... log in sync with this gate.

No further concerns on this path. Nice cleanup overall across all three commits.

[resolve]

@mikhailm-coder mikhailm-coder merged commit a85a117 into master Jul 7, 2026
4 checks passed
@mikhailm-coder mikhailm-coder deleted the cleanup/remove-mesh-offline-diag-logs branch July 7, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants